package pl.elka.pobr.ppr.logic;

public class MaskEngine {

    public static final int[][] BLUR_MASK = {{1, 2, 1}, {2, 4, 2}, {1, 2, 1}};

    /**
     * puts a desired mask on the image
     * 
     * @param org
     *            original image
     * @param mask
     *            desired mask (must be 3x3)
     * @param divideBySum
     *            flag determining if we need to divide result pixel value by mask sum
     * @return
     */
    public static Pixel[][] putMask(final Pixel[][] org, int[][] mask, boolean divideBySum) {
        int w = org.length;
        int h = org[0].length;
        int ms = mask.length; // mask size - we assume it is always 3x3 size
        Pixel[][] res = new Pixel[w][h];
        for (int y = 0; y < h; ++y) {
            for (int x = 0; x < w; ++x) {
                if (y == 0 || y == h - 1 || x == 0 || x == w - 1) {
                    res[x][y] = org[x][y];
                    continue; // don't mask edges
                }
                int maskSum = 0;
                long rr = org[x - 1][y - 1].r * mask[0][0] + org[x][y - 1].r * mask[0][1] + org[x + 1][y - 1].r * mask[0][2]
                        + org[x - 1][y].r * mask[0][0] + org[x][y].r * mask[0][1] + org[x + 1][y].r * mask[0][2]
                        + org[x - 1][y + 1].r * mask[0][0] + org[x][y + 1].r * mask[0][1] + org[x + 1][y + 1].r * mask[0][2];
                long gg = org[x - 1][y - 1].g * mask[0][0] + org[x][y - 1].g * mask[0][1] + org[x + 1][y - 1].g * mask[0][2]
                        + org[x - 1][y].g * mask[0][0] + org[x][y].g * mask[0][1] + org[x + 1][y].g * mask[0][2]
                        + org[x - 1][y + 1].g * mask[0][0] + org[x][y + 1].g * mask[0][1] + org[x + 1][y + 1].g * mask[0][2];
                long bb = org[x - 1][y - 1].b * mask[0][0] + org[x][y - 1].b * mask[0][1] + org[x + 1][y - 1].b * mask[0][2]
                        + org[x - 1][y].b * mask[0][0] + org[x][y].b * mask[0][1] + org[x + 1][y].b * mask[0][2]
                        + org[x - 1][y + 1].b * mask[0][0] + org[x][y + 1].b * mask[0][1] + org[x + 1][y + 1].b * mask[0][2];
                if (divideBySum) {
                    for (int i = 0; i < ms; ++i) {
                        for (int j = 0; j < ms; ++j) {
                            maskSum += mask[i][j];
                        }
                    }
                    rr /= maskSum;
                    gg /= maskSum;
                    bb /= maskSum;
                }
                // normalize values
                if (rr < 0) {
                    rr = 0;
                } else if (rr > 255) {
                    rr = 255;
                }
                if (gg < 0) {
                    gg = 0;
                } else if (gg > 255) {
                    gg = 255;
                }
                if (bb < 0) {
                    bb = 0;
                } else if (bb > 255) {
                    bb = 255;
                }
                res[x][y] = new Pixel((int) rr, (int) gg, (int) bb);
            }
        }
        return res;
    }
}
